//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>

static HANDLE g_hDrive = NULL;
void FileDriveClose(void)
{
    if (g_hDrive) {
        CloseHandle(g_hDrive);
        g_hDrive = NULL;
    }
}

HRESULT FileDriveOpenDisk(wchar_t *pName, UINT64 *pSize)
{
    HRESULT hr = NOERROR;
//    wprintf(L"FileDriveOpenDisk(wchar_t *pName: %s\n", pName);
    if (NULL != g_hDrive) {
        return E_ACCESSDENIED;
    }
    g_hDrive = CreateFileW(
                pName, GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (g_hDrive == INVALID_HANDLE_VALUE) {
        wprintf(L"DRIVE: Can not open disk: %s. ERROR NO.:%d\n", pName, GetLastError());
        return E_INVALIDARG;
    }

    *pSize = (UINT64)GetFileSize(g_hDrive, NULL);
    if (*pSize == INVALID_FILE_SIZE) {
        DWORD dwError = GetLastError() ;
        printf("DRIVE: %u Get the file size failed!\n", dwError);
        return E_INVALIDARG;
    }

    return hr;
}

int FileDriveRW(unsigned long Position, void *pBuffer, int Size, int Flags)
{
    DWORD NewFilePos;
    if (NULL == g_hDrive) {
        return 0;
    }
//    printf("FileDriveRW Position : %u\n", Position);
    NewFilePos = SetFilePointer(g_hDrive, Position, NULL, FILE_BEGIN);
    if (NewFilePos == DWORD(-1)) {
        printf("DRIVE: Set FilePointer failed %d\n", GetLastError());
        return 0;
    }
    //__asm int 3
    DWORD BytesRead;
    BOOL b;
    if (Flags == 0) {//Read sectors
        b = ReadFile(g_hDrive, pBuffer, Size, &BytesRead, NULL);
//        if(b) {
//            printf("READ %d BYTE SUCEED\n", BytesRead);
//        } else {
//            printf("READ FAIL\n");
//        }
    }
    else {//Write Sectors
        b = WriteFile(g_hDrive, pBuffer, Size, &BytesRead, NULL);
        FlushFileBuffers(g_hDrive);//Write out all buffer data
//        if(b) {
//            printf("WRITE %d BYTE SUCEED\n", BytesRead);
//        } else {
//            printf("WRITE FAIL\n");
//        }
    }
    if (!b) {
        printf("DRIVE: IO FAIL\n");
    }

    return BytesRead;
}
